package Screens;

import Objects.CPrinny;
import Objects.CPrinny.PrinnyGeneralState;
import Utils.GameUtils;
import Utils.SoundManager;
import Objects.CQuadTree;
import Objects.CRect;
import Objects.CObject;
import Objects.CQuadNode;
import Objects.CObjectsList;
import Utils.GameInformation;
import Utils.CFile;
import Utils.CCamera;
import Objects.ObjectNode;
import Objects.AllSprite;

import com.badlogic.gdx.Screen;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.InputProcessor;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.audio.Sound;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.Texture.TextureFilter;
import com.badlogic.gdx.graphics.g2d.Animation;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector3;
import com.acumenvn.pent.MyPent;



public class GameScreen implements Screen {

	Sound mSoundEscape;
	Sound mMusicMainBackground;
	MyPent mGame;
	CPrinny myPrinny;
	SpriteBatch mBatch;
	Texture mBackgroundMap;
	float dt;
	CQuadTree mQuadTree;
	CQuadTree mQuadTree_map1;
	CQuadTree mQuadTree_map2;
	int currentMap;
	OrthographicCamera mCamera;
	OrthographicCamera mCamera2;
	CObjectsList mListObjects;
	AllSprite mAllSprite;
	private Rectangle glViewport;
	
	InputProcessor mInputProcessor = new InputProcessor() {
		
		@Override
		public boolean touchUp(int screenX, int screenY, int pointer, int button) {
			// TODO Auto-generated method stub
			return false;
		}
		
		@Override
		public boolean touchDragged(int screenX, int screenY, int pointer) {
			// TODO Auto-generated method stub
			return false;
		}
		
		@Override
		public boolean touchDown(int screenX, int screenY, int pointer, int button) {
			// TODO Auto-generated method stub
			return false;
		}
		
		@Override
		public boolean scrolled(int amount) {
			// TODO Auto-generated method stub
			return false;
		}
		
		@Override
		public boolean mouseMoved(int screenX, int screenY) {
			// TODO Auto-generated method stub
			return false;
		}
		
		@Override
		public boolean keyUp(int keycode) {
			// TODO Auto-generated method stub
			if(keycode == Keys.LEFT || keycode == Keys.RIGHT) {
				myPrinny.generalState = PrinnyGeneralState.Stand.ordinal();
			}
			return false;
		}
		
		@Override
		public boolean keyTyped(char character) {
			// TODO Auto-generated method stub
			return false;
		}
		
		@Override
		public boolean keyDown(int keycode) {
			// TODO Auto-generated method stub
			switch (keycode) {
			case Keys.SPACE:
//				myPrinny.generalState = PrinnyGeneralState.Shoot.ordinal();
				break;
			case Keys.UP:
//				myPrinny.jump(dt);
//				myPrinny.generalState = PrinnyGeneralState.Jump.ordinal();
				break;
			case Keys.ESCAPE:
				SoundManager.getInstance().playSound(mSoundEscape);
				mGame.setScreen(new MenuInGameScreen(mGame));
				break;
			case Keys.X:
				mGame.setScreen(new GameOverScreen(mGame));
				break;
			default:
				break;
			}
			return false;
		}
	};
	
	// Constructor
	public GameScreen(MyPent game) {
		// TODO Auto-generated constructor stub
		this.mGame = game;
		glViewport = new Rectangle(0, 0, 480, 320);
		mCamera = new OrthographicCamera(480,320);
		mCamera.position.set(0, 0, 0);
		mCamera2 = new OrthographicCamera(100, 50);
		myPrinny = CPrinny.getInstance();
		
//		myPrinny.setPosition(0, 0);
//		myPrinny.setIsRight(true);
//		myPrinny.generalState = PrinnyGeneralState.Stand.ordinal();
//		mAllSprite = new AllSprite();
//		myPrinny.initSprites();
//		initMap();
//		currentMap = GameUtils.getInstance().getMapIndex();
//		
//		loadMap();
//		mListObjects = new CObjectsList();
//		myPrinny.setInputHandler(mInputProcessor);
//		myPrinny.initSprites();
	} 
	
	@Override
	public void render(float delta) {
		// TODO Auto-generated method stub
//		updateGamePlay(delta);
		dt = delta;
		Gdx.gl20.glClear(GL20.GL_COLOR_BUFFER_BIT);
		Gdx.gl20.glViewport((int)glViewport.x, (int)glViewport.y, (int)glViewport.width, (int)glViewport.height);
		mCamera.update();
		
//		mCamera.apply(Gdx.gl10);
		mBatch.begin();
//		mBatch.maxSpritesInBatch = 2;
		
//		myPrinny.setSpriteBatch(mBatch);
		mBatch.draw(mBackgroundMap, 0, 0);
//		myPrinny.drawPrinny(delta, mBatch, mQuadTree);
//		renderGamePlay(delta);
		mBatch.end();
		handleInputForCamera();
//		handleInputForPrinny();
//		myPrinny.move(delta);
	}

	private void handleInputForCamera() {
		// TODO Auto-generated method stub
		float mX = mCamera.position.x;
		float mY = mCamera.position.y;
		float mZ = mCamera.position.z;
		if(Gdx.input.isKeyPressed(Keys.LEFT)) {
			mCamera.position.set(mCamera.position.x - 10, mCamera.position.y, mCamera.position.z);
		}
		
		if(Gdx.input.isKeyPressed(Keys.RIGHT)) {
			mCamera.position.set(mX + 10, mY, mZ);
		}
		
		if(Gdx.input.isKeyPressed(Keys.UP)) {
			mCamera.position.set(mX, mY + 10, mZ);
		}
		
		if(Gdx.input.isKeyPressed(Keys.DOWN)) {
			mCamera.position.set(mX, mY - 10, mZ);
		}
		mCamera.translate(new Vector3(mX, mY, mZ));
	}

	@Override
	public void resize(int width, int height) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void show() {
		// TODO Auto-generated method stub
		mBatch = new SpriteBatch();
		mSoundEscape = SoundManager.getInstance().getSoundSelectMenu();
		Gdx.input.setInputProcessor(mInputProcessor);
		
		mMusicMainBackground = SoundManager.getInstance().getMusicMainBackground();
//		SoundManager.getInstance().playSoundWithLoop(mMusicMainBackground);
		Gdx.graphics.setContinuousRendering(true);
		Gdx.graphics.requestRendering();
		
		if(GameUtils.getInstance().getMapIndex() == 1) {
			mBackgroundMap = new Texture(Gdx.files.internal("Images/UNIT/Background1.png"));
		} else {
			mBackgroundMap = new Texture(Gdx.files.internal("Images/UNIT/Background2.png"));
		}
		
		mBackgroundMap.setFilter(TextureFilter.Linear, TextureFilter.Linear);
	}

	@Override
	public void hide() {
		// TODO Auto-generated method stub
		SoundManager.getInstance().stopSound(mMusicMainBackground);
	}

	@Override
	public void pause() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void resume() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void dispose() {
		// TODO Auto-generated method stub
		mBackgroundMap.dispose();
		mBatch.dispose();
	}

	private void handleInputForPrinny() {
		if(Gdx.input.isKeyPressed(Keys.LEFT)) {
			myPrinny.setIsRight(false);
		} else if(Gdx.input.isKeyPressed(Keys.RIGHT)) {
			myPrinny.setIsRight(true);
		}
	}
	
	private void initMap() {
		int sizeTile = GameInformation.getInstance().getSizeTile();
		mQuadTree_map1 = new CQuadTree(sizeTile*300, sizeTile*300);
		CFile.getInstance().readFile(mQuadTree_map1, "Map1.txt");
		mQuadTree_map2 = new CQuadTree(sizeTile*300, sizeTile*300);
		CFile.getInstance().readFile(mQuadTree_map2, "Map2.txt");
	}
	
	private void loadMap() {
		switch (currentMap) {
		case 1:
			mQuadTree = mQuadTree_map1;
			break;
		case 2:
			mQuadTree = mQuadTree_map2;
			break;
		default:
			break;
		}
		mCamera.position.x = mQuadTree.m_fX;
		mCamera.position.y = mQuadTree.m_fY;
		mCamera.position.z = 0f;
		// Load main character in here
		myPrinny.camera = mCamera;
		myPrinny.setPosition(mQuadTree.m_fX, mQuadTree.m_fY);
		mQuadTree.setHealth(mQuadTree.m_root);
	}
	
	private void updateGamePlay(float dt) {
		loadMap();
		CFile.getInstance().saveFile(GameUtils.getInstance().getMapIndex(), myPrinny.getPosition().x, myPrinny.getPosition().y);
		mCamera.viewportHeight = mQuadTree.m_root.m_rect.getBottom();
		mCamera.viewportWidth = mQuadTree.m_root.m_rect.getRight();
		mCamera.position.x = myPrinny.getPosition().x - 400 + myPrinny.getWidth()/2;
		mCamera.position.y = myPrinny.getPosition().y - 300 + myPrinny.getHeight()/2;
		mListObjects.resetListObjects();
		mQuadTree.setObjectsList(mListObjects, new CRect(mCamera.position.x, mCamera.position.y, 800, 600));
	}
	
	private void renderGamePlay(float dt) {
		//////////////////////////////////////////////////////////////////////////
		/// Background
		//////////////////////////////////////////////////////////////////////////
		ObjectNode tempNode = mListObjects.m_head;
		while(tempNode != null) {
			if(tempNode.m_object.m_health > 0 &&
				CRect.checkCollisionBetween2Rect(tempNode.m_object.m_workingArea, new CRect(mCamera.position.x,mCamera.position.y, 800, 600))) {	
			}
			tempNode = tempNode.m_nextNode;
		}
		//////////////////////////////////////////////////////////////////////////
		/// Background1
		//////////////////////////////////////////////////////////////////////////
		tempNode = mListObjects.m_head;
		while(tempNode != null) {
			if(tempNode.m_object.m_health > 0 && 
				CRect.checkCollisionBetween2Rect(tempNode.m_object.m_workingArea, new CRect(mCamera2.position.x, mCamera2.position.y, 800, 600))) {
				char style = tempNode.m_object.m_style;
				if(style == GameInformation.getInstance().getUnit_Background1()) {
					
					mAllSprite.m_background1.setPosition(tempNode.m_object.m_rect.getLeft() - (mCamera2.position.x), tempNode.m_object.m_rect.getLeft() - mCamera2.position.y - 50);
					mAllSprite.m_background1.draw(mBatch);
				}
			}
			tempNode = tempNode.m_nextNode;
		}
		//////////////////////////////////////////////////////////////////////////
		/// Background2
		//////////////////////////////////////////////////////////////////////////
		tempNode = mListObjects.m_head;
		while(tempNode != null) {
			if(tempNode.m_object.m_health > 0 && 
					CRect.checkCollisionBetween2Rect(tempNode.m_object.m_workingArea, new CRect(mCamera2.position.x, mCamera2.position.y, 800, 600))) {
				char style = tempNode.m_object.m_style;
				if(style == GameInformation.getInstance().getUnit_Background2()) {
					mAllSprite.m_background2.setPosition(tempNode.m_object.m_rect.getLeft() - mCamera2.position.x, tempNode.m_object.m_rect.getLeft() - mCamera2.position.y - 50);
					mAllSprite.m_background2.draw(mBatch);
				}
			}
			tempNode = tempNode.m_nextNode;
		}
		//////////////////////////////////////////////////////////////////////////
		/// Grass
		//////////////////////////////////////////////////////////////////////////
		tempNode = mListObjects.m_head;
		while(tempNode != null) {
			if(tempNode.m_object.m_health > 0 && 
					CRect.checkCollisionBetween2Rect(tempNode.m_object.m_workingArea, new CRect(mCamera.position.x, mCamera.position.y, 800, 600))) {
				char style = tempNode.m_object.m_style;
				if(style == GameInformation.getInstance().getUnit_Grass1()) {
					mAllSprite.m_grass1.setPosition(tempNode.m_object.m_rect.getLeft() - mCamera.position.x, tempNode.m_object.m_rect.getTop() - mCamera.position.y - 50);
					mAllSprite.m_grass1.draw(mBatch);
				}
			}
			tempNode = tempNode.m_nextNode;
		}
		//////////////////////////////////////////////////////////////////////////
		/// Grass1M2
		//////////////////////////////////////////////////////////////////////////
		tempNode = mListObjects.m_head;
		while(tempNode != null) {
			if(tempNode.m_object.m_health > 0 && 
					CRect.checkCollisionBetween2Rect(tempNode.m_object.m_workingArea, new CRect(mCamera.position.x, mCamera.position.y, 800, 600))) {
				char style = tempNode.m_object.m_style;
				if(style == GameInformation.getInstance().getUnit_Grass1M2()) {
					mAllSprite.m_grass1m2.setPosition(tempNode.m_object.m_rect.getLeft() - mCamera.position.x, tempNode.m_object.m_rect.getTop() - mCamera.position.y);
					mAllSprite.m_grass1m2.draw(mBatch);
				}
			}
			tempNode = tempNode.m_nextNode;
		}
		//////////////////////////////////////////////////////////////////////////
		/// Grass2M2
		//////////////////////////////////////////////////////////////////////////
		tempNode = mListObjects.m_head;
		while(tempNode != null) {
			if(tempNode.m_object.m_health > 0 && 
					CRect.checkCollisionBetween2Rect(tempNode.m_object.m_workingArea, new CRect(mCamera.position.x, mCamera.position.y, 800, 600))) {
				char style = tempNode.m_object.m_style;
				if(style == GameInformation.getInstance().getUnit_Grass2M2()) {
					mAllSprite.m_grass2m2.setPosition(tempNode.m_object.m_rect.getLeft() - mCamera.position.x, tempNode.m_object.m_rect.getTop() - mCamera.position.y);
					mAllSprite.m_grass2m2.draw(mBatch);
				}
			}
			tempNode = tempNode.m_nextNode;
		}
		//////////////////////////////////////////////////////////////////////////
		/// save
		//////////////////////////////////////////////////////////////////////////
		tempNode = mListObjects.m_head;
		while(tempNode != null) {
			if(tempNode.m_object.m_health > 0 && 
					CRect.checkCollisionBetween2Rect(tempNode.m_object.m_workingArea, new CRect(mCamera.position.x, mCamera.position.y, 800, 600))) {
				char style = tempNode.m_object.m_style;
				if(style == GameInformation.getInstance().getUnit_Save()) {
					mAllSprite.m_save.setPosition(tempNode.m_object.m_rect.getLeft() - mCamera.position.x, tempNode.m_object.m_rect.getTop() - mCamera.position.y);
					mAllSprite.m_save.draw(mBatch);
				}
			}
			tempNode = tempNode.m_nextNode;
		}
		//////////////////////////////////////////////////////////////////////////
		/// End
		//////////////////////////////////////////////////////////////////////////
//		tempNode = mListObjects.m_head;
//		while(tempNode != null) {
//			if(tempNode.m_object.m_health > 0 && 
//					CRect.checkCollisionBetween2Rect(tempNode.m_object.m_workingArea, new CRect(mCamera.position.x, mCamera.position.y, 800, 600))) {
//				char style = tempNode.m_object.m_style;
//				if(style == GameInformation.getInstance().getUnit_End()) {
//					mAllSprite.m_end.setPosition(tempNode.m_object.m_rect.getLeft() - mCamera.position.x, tempNode.m_object.m_rect.getTop() - mCamera.position.y);
//					mAllSprite.m_end.draw(mBatch);
//				}
//			}
//			tempNode = tempNode.m_nextNode;
//		}
		//////////////////////////////////////////////////////////////////////////
		/// Ground
		//////////////////////////////////////////////////////////////////////////
		tempNode = mListObjects.m_head;
		while(tempNode != null) {
			if(tempNode.m_object.m_health > 0 && 
					CRect.checkCollisionBetween2Rect(tempNode.m_object.m_workingArea, new CRect(mCamera.position.x, mCamera.position.y, 800, 600))) {
				char style = tempNode.m_object.m_style;
				if(style == GameInformation.getInstance().getUnit_Ground1()) {
					mAllSprite.m_ground1.setPosition(tempNode.m_object.m_rect.getLeft() - mCamera.position.x, tempNode.m_object.m_rect.getTop() - mCamera.position.y);
					mAllSprite.m_ground1.draw(mBatch);
				}
			}
			tempNode = tempNode.m_nextNode;
		}
		//////////////////////////////////////////////////////////////////////////
		/// GroundM2
		//////////////////////////////////////////////////////////////////////////
		tempNode = mListObjects.m_head;
		while(tempNode != null) {
			if(tempNode.m_object.m_health > 0 && 
					CRect.checkCollisionBetween2Rect(tempNode.m_object.m_workingArea, new CRect(mCamera.position.x, mCamera.position.y, 800, 600))) {
				char style = tempNode.m_object.m_style;
				if(style == GameInformation.getInstance().getUnit_Ground1M2()) {
					mAllSprite.m_groundm2.setPosition(tempNode.m_object.m_rect.getLeft() - mCamera.position.x, tempNode.m_object.m_rect.getTop() - mCamera.position.y);
					mAllSprite.m_groundm2.draw(mBatch);
				}
			}
			tempNode = tempNode.m_nextNode;
		}
		
		//////////////////////////////////////////////////////////////////////////
		/// Rock1 units
		//////////////////////////////////////////////////////////////////////////
		tempNode = mListObjects.m_head;
		while(tempNode != null) {
			if(tempNode.m_object.m_health > 0 && 
					CRect.checkCollisionBetween2Rect(tempNode.m_object.m_workingArea, new CRect(mCamera.position.x, mCamera.position.y, 800, 600))) {
				char style = tempNode.m_object.m_style;
				if(style == GameInformation.getInstance().getUnit_Rock1()) {
					mAllSprite.m_rock1.setPosition(tempNode.m_object.m_rect.getLeft() - mCamera.position.x, tempNode.m_object.m_rect.getTop() - mCamera.position.y);
					mAllSprite.m_rock1.draw(mBatch);
				}
			}
			tempNode = tempNode.m_nextNode;
		}
		//////////////////////////////////////////////////////////////////////////
		/// RockM2 units
		//////////////////////////////////////////////////////////////////////////
		tempNode = mListObjects.m_head;
		while(tempNode != null) {
			if(tempNode.m_object.m_health > 0 && 
					CRect.checkCollisionBetween2Rect(tempNode.m_object.m_workingArea, new CRect(mCamera.position.x, mCamera.position.y, 800, 600))) {
				char style = tempNode.m_object.m_style;
				if(style == GameInformation.getInstance().getUnit_RockM2()) {
					mAllSprite.m_rockm2.setPosition(tempNode.m_object.m_rect.getLeft() - mCamera.position.x, tempNode.m_object.m_rect.getTop() - mCamera.position.y);
					mAllSprite.m_rockm2.draw(mBatch);
				}
			}
			tempNode = tempNode.m_nextNode;
		}
		//////////////////////////////////////////////////////////////////////////
		/// Cloud units
		//////////////////////////////////////////////////////////////////////////
		tempNode = mListObjects.m_head;
		while(tempNode != null) {
			if(tempNode.m_object.m_health > 0 && 
					CRect.checkCollisionBetween2Rect(tempNode.m_object.m_workingArea, new CRect(mCamera.position.x, mCamera.position.y, 800, 600))) {
				char style = tempNode.m_object.m_style;
				if(style == GameInformation.getInstance().getUnit_Cloud()) {
					mAllSprite.m_cloud.setPosition(tempNode.m_object.m_rect.getLeft() - mCamera.position.x, tempNode.m_object.m_rect.getTop() - mCamera.position.y);
					mAllSprite.m_cloud.draw(mBatch);
				}
			}
			tempNode = tempNode.m_nextNode;
		}
		// Ve prinny
		if(myPrinny.mHeal > 0) {
			myPrinny.update(dt, mQuadTree);
			
			myPrinny.drawPrinny(dt, mBatch, mQuadTree);
		}
		
		// So luong mang
		if(myPrinny.getLife() >= 0) {
			for (int i = 1; i < myPrinny.getLife(); i++) {
				mAllSprite.m_life.setPosition((i-1)*35+5, 0);
				mAllSprite.m_life.draw(mBatch);
			}
		}
	}
}
